package world.snowcrystal.aa;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.log4j.Log4j2;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import world.snowcrystal.dao.UserAuthenticationDetails;
import world.snowcrystal.mapper.UserAuthenticationDetailsMapper;

@Log4j2
@Component("userDetailsService")
public class DefaultUserDetailsService implements UserDetailsService {


    private final UserAuthenticationDetailsMapper mapper;

    public DefaultUserDetailsService(UserAuthenticationDetailsMapper mapper) {
        this.mapper = mapper;
    }


    /**
     * Locates the user based on the username. In the actual implementation, the search
     * may possibly be case sensitive, or case insensitive depending on how the
     * implementation instance is configured. In this case, the <code>UserDetails</code>
     * object that comes back may have a username that is of a different case than what
     * was actually requested..
     *
     * @param username the username identifying the user whose data is required.
     * @return a fully populated user record (never <code>null</code>)
     * @throws UsernameNotFoundException if the user could not be found or the user has no
     *                                   GrantedAuthority
     */
    @Override
    public UserDetails loadUserByUsername(String username)
            throws UsernameNotFoundException {
        log.info("UserDetailsService : try to load user {}", username);

        if (!StringUtils.hasText(username)) {
            throw new UsernameNotFoundException(username);
        }
        QueryWrapper<UserAuthenticationDetails> wrapper = new QueryWrapper<>();
        wrapper.checkSqlInjection()
                .eq("username", username);
        UserAuthenticationDetails uad = null;

        uad = mapper.selectOne(wrapper, false);
        //TODO 接口要求需要对用户权限进行校验
        // 但是现在暂时不考虑权限问题
        // 以后会提供这个功能，而且权限也并不在这里校验
        // SpringSecurity 有专属的架构
        if(uad == null) {
            throw new UsernameNotFoundException(username);
        }
        return uad;
    }
}
